import { ArrayList, HashMap } from '@kit.ArkTS';

type EventGeneralData = { [key: string]: any } | any;


export class EventEmitter {
  private onHashMap: HashMap<string, ArrayList<EventGeneralData>> = new HashMap();
  private onceHashMap: HashMap<string, ArrayList<EventGeneralData>> = new HashMap();
  private nextTickData: HashMap<string, EventGeneralData> = new HashMap();

  constructor() {
  }


  on(event: string, listener: (...args: EventGeneralData) => void) {
    if (this.onHashMap.hasKey(event)) {
      this.onHashMap.get(event).add(listener)
    } else {
      let array = new ArrayList<EventGeneralData>();
      array.add(listener);
      this.onHashMap.set(event, array);
    }
    if (this.nextTickData.hasKey(event)) {
      let params = this.nextTickData.get(event);
      if (Array.isArray(params)) {
        listener(...params)
      } else {
        listener(params)
      }

    }
  }

  once(event: string, listener: (...args: EventGeneralData[]) => void) {

    if (this.onceHashMap.hasKey(event)) {
      this.onceHashMap.get(event).add(listener)
    } else {
      let array = new ArrayList<EventGeneralData>();
      array.add(listener);
      this.onceHashMap.set(event, array);
    }
    if (this.nextTickData.hasKey(event)) {
      let params = this.nextTickData.get(event);
      if (Array.isArray(params)) {
        listener(...params)
      } else {
        listener(params)
      }
      this.onHashMap.remove(event);
    }
  }

  off(event: string) {
    if (this.onHashMap.hasKey(event)) {
      this.onHashMap.remove(event);
    }
    if (this.onceHashMap.hasKey(event)) {
      this.onHashMap.remove(event);
    }
  }


  emit(event: string, ...args: EventGeneralData[]) {

    if (this.onHashMap.hasKey(event)) {
      let callbackArrays = this.onHashMap.get(event)
      callbackArrays.forEach((callback, i) => {
        callback(args);
      })

    } else if (this.onceHashMap.hasKey(event)) {
      let callbackArrays = this.onceHashMap.get(event)
      callbackArrays.forEach((callback, i) => {
        callback(args);
      })
      this.onceHashMap.remove(event);
    }
  }

  nextTickEmit(event: string, ...args: EventGeneralData) {
    if (this.nextTickData.hasKey(event)) {
      this.nextTickData.replace(event, args);
    } else {
      this.nextTickData.set(event, args);
    }
    //若是存在，直接发送
    if (this.onHashMap.hasKey(event)) {
      let callbackArrays = this.onHashMap.get(event)
      callbackArrays.forEach((callback, i) => {
        callback(args);
      })

    } else if (this.onceHashMap.hasKey(event)) {
      let callbackArrays = this.onceHashMap.get(event)
      callbackArrays.forEach((callback, i) => {
        callback(args);
      })
      this.onceHashMap.remove(event);
    }
  }
}